#pragma once

#include "Enviroment.h"
#include "Error.h"
#include "Parser.h"
#include "Scope.h"
#include "VisitorInterface.h"

namespace FlooP
{
	class Compiler : private VisitorInterface
	{
		public:
		
		static void Compile (Environment& env, std::shared_ptr<AST> ast);

		private:

		Compiler (Environment& env);

		virtual void visit (const AST& ast);
		virtual void visit (const ASTProcedure& procedure);

		virtual void visit (const ASTBlock& block, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTIf& if_stmt, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTLoop& loop, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTMuLoop& loop, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTAbort& abort, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTQuit& quit, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTAssignment& assign, std::shared_ptr<Procedure> func);

		virtual void visit (const ASTCompare& expr, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTBinaryMathOp& expr, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTCell& expr, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTProcedureCall& expr, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTIdentifier& expr, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTNumber& num, std::shared_ptr<Procedure> func);
		virtual void visit (const ASTString& str, std::shared_ptr<Procedure> func);

		Environment& m_env;
	};
}